package lockTest;

import java.io.IOException;
import java.util.Random;

public class ReadWriteLock {

    private volatile int state;

    private Object readLock = new Object();
    private Object writeLock = new Object();

    public synchronized void readLock() {
        while (true) {
            if (state >= 0) {
                state += 1;
                break;
            } else {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized void unlockRead() {
        state -= 1;
        if (state == 0) {
            this.notify();
        }
    }

    public synchronized void writeLock(){
        while (true) {
            if (state == 0) {
                state = -1;
                break;
            } else {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized void unlockWrite() {
        state = 0;
        this.notifyAll();
    }

    public static void main(String[] args) throws IOException {
        ReadWriteLock readWriteLock = new ReadWriteLock();
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            int num = random.nextInt(10);
            final int id = i;
            if (num > 5) {
                new Thread(() -> {
                    readWriteLock.readLock();
                    System.out.println("read start-" + id);
                    try {
                        Thread.sleep(new Random().nextInt(10) * 100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("read end-" + id);
                    readWriteLock.unlockRead();
                }).start();
            } else {
                new Thread(() -> {
                    readWriteLock.writeLock();
                    System.out.println("write start-" + id);
                    try {
                        Thread.sleep(new Random().nextInt(10) * 100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("write end-" + id);
                    readWriteLock.unlockWrite();
                }).start();
            }
            System.out.println("启动了" + id);
        }
    }
}
